leisurexi's Blog.

MySQL EXPLAIN详解

字数统计: 2.1k阅读时长: 7 min
2020/01/18 Share

本篇文章主要介绍 MySQL 中 EXPLAIN 命令的使用。

EXPLAIN的作用

在日常工作中,我们会有时会开慢查询去记录一些执行时间比较就的 SQL 语句,找出这些 SQL 语句并不意味着完事了,此时我们常常用到 EXPLAIN 这个命令来查看一下这些 SQL 语句的执行计划,查看该 SQL 语句有没有使用上索引,有没有做全表扫描,这都可以通过 EXPLAIN 命令来查看。所以我们深入了解 MySQL 的基于开销的优化器,还可以获得很多可能被优化器考虑到的访问策略的细节,以及当运行 SQL 语句时哪种策略预计会被优化器采用。

EXPLAIN各字段解释

对于一个200万数据的表在 name 字段没建立索引的情况下执行 explain select name from user order by name desc ,结果如下所示:

1. id

执行编号,表示 select 所属的行。如果在语句中没子查询或关联查询,只有唯一的 select ,每行都将显示1。否则,内层的 select 语句一般会顺序编号,对应于其在原始语句中的位置。

2. select_type

表示查询的类型 。如果查询有任何复杂的子查询,则最外层标记为 PRIMARY (DERIVED、UNION、UNION RESULT)

  • simple: 简单子查询,不包含子查询和 union。

  • primary: 包含 union 或者子查询,最外层的部分标记为 primary。

  • derived: 派生表——该临时表是从子查询派生出来的,位于 form 中的子查询。

  • union: 位于 union 中第二个及其以后的子查询被标记为 union,第一个就被标记为 primary 。如果 union 位于 from 中则标记为 derived。

  • union result: 用来从匿名临时表里检索结果的 select 被标记为 union result。

  • dependent union: 顾名思义,首先需要满足 union 的条件,及 union 中第二个以及后面的 select 语句,同时该语句依赖外部的查询。

  • subquery: 一般子查询中的子查询被标记为 subquery,也就是位于 select 列表中的查询。

  • dependent subquery: 首先需要满足 subquery 的条件,及 subquery 中第二个以及后面的 select 语句,同时该语句依赖外部的查询。

3. table

对应行正在访问哪一个表,表名或者别名。

  • 关联优化器会为查询选择关联顺序,左侧深度优先。
  • from 中有子查询的时候,表明是 derivedN 的形式,N 指向子查询,也就是 explain 结果中的下一列。
  • 当有 union result 的时候,表明是 union 1,2 等的形式,1,2 表示参与 unionquery id

注意:MySQL 对待这些表和普通表一样,但是这些 “临时表” 是没有任何索引的。

4. type

找到数据的方式,根据效率从高到低排序有如下几种:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL ,一般来说,得保证查询至少达到 range 级别,最好能达到 ref ,否则这条语句是需要优化的。

  • ALL: 最坏的情况,全表扫描。
  • index: 和全表扫描一样。只是扫描表的时候按照索引次序进行而不是行。主要优点就是避免了排序,但是开销仍然非常大。如在 Extra 列看到 Using index,说明正在使用覆盖索引,只扫描索引的数据,它比按索引次序全表扫描的开销要小很多。
  • range: 范围扫描,一个有限制的索引扫描。key 列显示使用了哪些索引。当时用 =、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN、IN 操作符时,用常量比较关键字列时,可以使用 range。
  • index_merage: 用在范围查询中,然后尝试合并多个索引检索的结果。当查询的条件有多个索引时,index_merage 只会选择其二合并索引。index_merage 只能扫描单表,不能跨表扫描。
  • ref: 一种索引访问,他返回所有匹配某个单个值的行。此类索引访问只有当使用非唯一性索引或唯一性索引。
  • eq_ref: 最多只返回一条符合条件的记录。使用唯一性索引或主键查找时会发生 (高效)。
  • const: 当确定最多只会有一行匹配的时候, MySQL 优化器会在查询前读取它而且只读取一次,因此非常快。当主键放入 where 子句时,MySQL 把这个查询转为一个常量 (高效)。
  • system: 这是 const 连接类型的一种特例,表仅有一行满足条件。
  • Null: 意味说 MySQL 能在优化阶段分解查询语句,在执行阶段甚至用不到访问表或索引 (高效)。

5. possible_key

显示查询可能使用了哪些索引,表示该索引可以进行高效地查找,但是列出来的索引对于后续优化过程可能是没有用的。

6. key

显示查询十几决定使用的键(索引) 。如果没有选择键,值是 Null 。要想前置 MySQL 使用或忽视 。

7. Possible_key

列中的索引,在查询中使用 FORCE INDEX、USE INDEX 、IGNORE INDEX

8. Key_len

显示 MySQL 决定使用的键长度。如果键是 Null ,则长度为 Null 。使用的索引的长度,再不损失精确性的情况下,长度越短越好。

9. ref

显示使用哪个列或常数与 key 一起从表中选择行。

10. rows

为了找到所需的行而需要读取的行数,估算值,不精确。通过把所有的 rows 列值相乘,可粗略估算整个查询会检查的行数。

11. Extra

ExtraEXPLAIN 输出中另外一个很重要的列,该列显示 MySQL 在查询过程中的一些详细信息,MySQ L查询优化器执行查询的过程中对查询计划的重要补充信息。

  • Using filesort: 表示 MySQL 在对查询结果使用一个外部索引排序,而不是从表里按索引次序读到相关内容,可能在内存或者磁盘上进行排序。MySQL 中无法利用索引完成的排序操作称为 文件排序
  • Using temporary: 表示 MySQL 在对查询结果排序时使用临时表,常见于 order bygroup by
  • Not exists: MySQL 优化了 LEFT JOIN ,一旦它找到了匹配 LEFT JOIN 标准的行,就不再搜索了。
  • Using index: 说明查询时覆盖了索引的,不需要读取数据文件,从索引树(索引文件)中即可获得信息。如果同时出现 using where ,表明索引被用来执行索引键值得查找,没有 using where ,表明索引用来读取数据而非执行查找动作。这是 MySQL 服务层完成的,但无需再回表查询记录。
  • Using index condition: 这是 MySQL 5.6 出来的新特性,叫做 “索引条件推送” 。简单说一点就是 MySQL 原来在索引上是不能执行如 like 这样的操作的,但是现在可以了,这样减少了不必要的 I/O 操作,但是只能用在二级索引上。
  • Using where: 使用了 where 从句来限制哪些行将于下一张表匹配或者是返回给用户。注意:Extra 列出现 Using where 表示 MySQL 服务器将存储引擎返回服务层以后在应用 where 条件过滤
  • Using join buffer: 使用了连接缓存:Block Netsted Loop ,连接算法是嵌套循环连接;Batched Key Access ,连接算法是批量索引连接。
  • impossible where: where 子句的值总是 false ,不能用来获取任何元组 (记录)。
  • select tables optimized away: 在没有 group by 子句的情况下,给予索引优化 min/max 操作,或者对于 MyISAM 存储引擎优化 count(*) 操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。
  • distinct: 优化 dinstinct 操作,在找到第一匹配的元组后即停止找同样值的动作。

总结

  • EXPLAIN 不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况。
  • EXPLAIN 不考虑各种 Cache
  • EXPLAIN 不能显示 MySQL 在执行计划查询时所作的优化工作。
  • EXPLAIN 显示的部分统计信息是估算的,并非精确值。
  • EXPLAIN 只能解释 SELECT 操作,其它操作要重写为 SELECT 后查看执行计划。

参考

https://www.jianshu.com/p/ea3fc71fdc45

https://www.jianshu.com/p/4bde6f24c324

CATALOG
  1. 1. EXPLAIN的作用
  2. 2. EXPLAIN各字段解释
  3. 3. 总结
  4. 4. 参考